-
Notifications
You must be signed in to change notification settings - Fork 943
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
protocols/kad: Implement NetworkBehaviour::inject_address_change #1649
Conversation
With 826f513 a `StreamMuxer` can notify that the address of a remote peer changed. This is needed to support the transport protocol QUIC as remotes can change their IP addresses within the lifetime of a single connection. This commit implements the `NetworkBehaviour::inject_address_change` handler to update the Kademlia routing table accordingly.
Replace the old address with the new address iff the peer is in the routing table and the old address was found in the `Addresses` for the given peer.
Thanks for the review @romanb! With my recent changes a new address is only added to the
Can you expand on the scenario where the old address would not be present even though we are connected to the node? |
} | ||
|
||
// Update query address cache. | ||
for query in self.queries.iter_mut() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is a point in doing this, but I may be mistaken. The query address "cache" is used to make sure when a query wants to dial a certain address that often may not (yet) be in the routing table, that address is returned by addresses_of_peer
. Addresses in the routing table are always returned from addresses_of_peer
. So when the new address is successfully put in the routing table, it will be considered for dialing. Please correct me if I'm wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think there is a point in doing this, but I may be mistaken.
Is this not necessary for remote nodes that are not part of the local routing table?
Given two connected nodes: local node A and remote node B. Say node B is not in node A's routing table. Additionally node B is part of the QueryInner::addresses
list of an ongoing query on node A. Say Node B triggers an address change and then disconnects. Later on the earlier mentioned query on node A would like to connect to node B. Without replacing the address in the QueryInner::addresses
set node A would attempt to dial the old and not the new address.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given two connected nodes: local node A and remote node B. Say node B is not in node A's routing table. Additionally node B is part of the QueryInner::addresses list of an ongoing query on node A. Say Node B triggers an address change and then disconnects. Later on the earlier mentioned query on node A would like to connect to node B. Without replacing the address in the QueryInner::addresses set node A would attempt to dial the old and not the new address.
Fair enough, I guess given the right timing, this situation can occur. I still wonder though whether this is worth this special attention and effort. Maybe there is no good reason, but changing the addresses that a query discovered like this seems strange to me. At least it adds a subtle twist to reasoning about which addresses a query uses. The other aspect is that, depending on how often addresses change like this (certainly increasingly often the more peers you are connected to), iterating through all discovered addresses of that peer in all currently ongoing queries seems like a search for a needle in a haystack, if there is substantial traffic. Neither of these points is a good technical reason against doing this, I just had to express that I feel a bit uncomfortable about it and why that is. I guess the decision is yours, ultimately.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At least it adds a subtle twist to reasoning about which addresses a query uses.
That is a good point.
Still I would prefer to uphold correctness and revisit the decision once we have a transport protocol that supports address changes and the given logic proves to be a performance problem. I have included a note in ad81fd6 summarizing this discussion.
I don't remember what I had in mind at the time. Your new approach seems fine to me. |
Thank you for the help @romanb. |
With 826f513 a
StreamMuxer
can notify that the address of a remotepeer changed. This is needed to support the transport protocol QUIC as
remotes can change their IP addresses within the lifetime of a single
connection.
This commit implements the
NetworkBehaviour::inject_address_change
handler to update the Kademlia routing table accordingly.
Follow up for #1621.